#pragma once
#include "../Ode.h"

namespace Skill
{
	namespace Ode
	{
		ref class DVector3;
		ref class DQuaternion;

		public ref class DVector4 : DIUnmanagedPointer
		{
			INTERNAL_CLASS_DECLARATION(DVector4,dReal);
		public:
			UNMANAGEDPOINTER_DECLARATION();

			DVector4()
			{
				_SetPointer(new dVector4(),true);
			}
			DVector4(dReal x,dReal y,dReal z)
			{
				_SetPointer(new dVector4(),true);
				_This[0] = x;
				_This[1] = y;
				_This[2] = z;
				_This[3] = 1;
			}
			DVector4(dReal x,dReal y,dReal z,dReal w)
			{
				_SetPointer(new dVector4(),true);
				_This[0] = x;
				_This[1] = y;
				_This[2] = z;
				_This[3] = w;
			}
			DVector4(DVector4^ other)
			{
				_SetPointer(new dVector4(),true);
				_This[0] = other->_This[0];
				_This[1] = other->_This[1];
				_This[2] = other->_This[2];
				_This[3] = other->_This[3];
			}

			property dReal default[int]
			{
				dReal get(int index);
				void set(int index,dReal value);
			}

			VALUE_PROP_DECLARATION_GETSET(dReal,X);
			VALUE_PROP_DECLARATION_GETSET(dReal,Y);
			VALUE_PROP_DECLARATION_GETSET(dReal,Z);
			VALUE_PROP_DECLARATION_GETSET(dReal,W);

			void SetDQfromW(DVector3^ w, DQuaternion^ q);
			static DVector4^ DQfromW(DVector3^ w, DQuaternion^ q);

			///<summary> set a vector to all zeros </summary>
			void SetZero();

			///<summary> set a vector to specific value </summary>
			void SetValue(dReal value);

			///<summary> get the dot product of two vectors. </summary> 
			dReal Dot(DVector4^ a,DVector4^ b);

			///<summary> in matlab syntax: a(1:n) = a(1:n) .* d(1:n) </summary> 
			void Scale(DVector4^ d);

			virtual String^ ToString() override
			{
				return String::Format("X: {0} Y: {1} Z: {2} W: {3}",_This[0],_This[1],_This[2],_This[3]);
			}
		};
	}
}